package com.aisino.inveli.vinda.controller;

import com.aisino.inveli.vinda.VindamanagerApplication;
import com.aisino.inveli.vinda.entity.ConfigEntity;
import com.aisino.inveli.vinda.entity.GoodsDetail;
import com.aisino.inveli.vinda.entity.GoodsList;
import com.aisino.inveli.vinda.service.ConfigService;
import com.aisino.inveli.vinda.service.GoodsService;
import com.aisino.inveli.vinda.utils.AlertUtil;
import com.aisino.inveli.vinda.utils.ExcelUtils;
import com.aisino.inveli.vinda.utils.MathUtil;
import com.alibaba.fastjson.JSONObject;
import de.felixroske.jfxsupport.FXMLController;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.Window;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;

/**
 * @author leifeng
 * @Date 2017-11-10
 **/
@FXMLController
public class NextController implements Initializable{

    //-----------------------fsTableView（负数表格）-----------------------
    @FXML
    private TableView<GoodsDetail> fsTableView;
    @FXML
    private TableColumn<GoodsDetail,Integer> fsIdCol;
    @FXML
    private TableColumn<GoodsDetail,String> fsNameCol;
    @FXML
    private TableColumn<GoodsDetail,String> fsUnitCol;
    @FXML
    private TableColumn<GoodsDetail,String> fsSpecCol;
    @FXML
    private TableColumn<GoodsDetail,String> fsNumCol;
    @FXML
    private TableColumn<GoodsDetail,String> fsAmountCol;
    @FXML
    private Label fsTotalAmount;

    //---------------------------------------正数商品zsTableView------------------------------------------
    @FXML
    private TableView<GoodsDetail> zsTableView;
    @FXML
    private TableColumn<GoodsDetail,Integer> zsIdCol;
    @FXML
    private TableColumn<GoodsDetail,String> zsNameCol;
    @FXML
    private TableColumn<GoodsDetail,String> zsUnitCol;
    @FXML
    private TableColumn<GoodsDetail,String> zsSpecCol;
    @FXML
    private TableColumn<GoodsDetail,String> zsNumCol;
    @FXML
    private TableColumn<GoodsDetail,String> zsAmountCol;
    @FXML
    private TableColumn<GoodsDetail,Double> zsPriceCol;
    @FXML
    private TableColumn<GoodsDetail,String> zsDisCountCol;
    @FXML
    private TableColumn<GoodsDetail,String> adjustNumCol;
    @FXML
    private TableColumn<GoodsDetail,String> adjustAmountCol;
    @FXML
    private TableColumn<GoodsDetail,String> codeCol;
    @FXML
    private Text oracleAmount;
    @FXML
    private Text discountAmount;
    @FXML
    private Text ceAmount;
    @FXML
    private Text totalAmount;
    @FXML
    private Text noRateOracleAmount;
    @FXML
    private Text noRateDiscount;
    @FXML
    private Text disCount;
    @FXML
    private Text disRate;

    // ---------------------------Service-----------------------------------
    @Resource
    private ConfigService configService;
    @Resource
    private GoodsService goodsService;

    private GoodsList sysGoodList;

    private ConfigEntity sysConfigEntity;

    /**
     * 返回上一页
     */
    @FXML
    public void goPreView(){
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/view/main.fxml"));
        // 获取原页面
        VindamanagerApplication.showView(fxmlLoader);
    }

    /**
     * 跳转开具发票页面
     * @param event
     */
    @FXML
    public void goFpMainView(ActionEvent event){
        // 获取事件原窗体
        Window window = ((Button)event.getSource()).getScene().getWindow();
        if (Double.parseDouble(ceAmount.getText())!=0){
            Boolean flag = AlertUtil.confirmAlert("确定开具发票？", window, "仍有未调整的金额");
            if (!flag) {
                event.consume();
                return;
            }
        } else {
            Boolean flag = AlertUtil.confirmAlert("确定开具发票？", window, "");
            if (!flag) {
                event.consume();
                return;
            }
        }
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/view/invEli.fxml"));
        // 获取原页面
        fxmlLoader = VindamanagerApplication.showView(fxmlLoader);
        InvEliController controller = fxmlLoader.getController();
        controller.initData(sysGoodList,sysConfigEntity);
    }

    /**
     * 生成excel文件
     * @param event
     */
    @FXML
    private void exportExcelAction(ActionEvent event){
        // 获取事件原窗体
        Window window = ((Button)event.getSource()).getScene().getWindow();
        if (Double.parseDouble(ceAmount.getText())!=0){
            Boolean flag = AlertUtil.confirmAlert("是否继续？", window, "仍有未调整的金额");
            if (!flag) {
                event.consume();
                return;
            }
        } else {
            Boolean flag = AlertUtil.confirmAlert("确定生成文件？", window, "");
            if (!flag) {
                event.consume();
                return;
            }
        }
        // excel导出
        JSONObject json;
        if (sysConfigEntity.getIsRate()){
            json = ExcelUtils.getXLSFile(sysGoodList,sysConfigEntity);
        }else {
            json = ExcelUtils.getXLSFileByNoRateMon(sysGoodList,sysConfigEntity);
        }
        if (json.getBoolean("status")) {
            AlertUtil.showInfoAlert("","文件生成成功",window);
        }else {
            AlertUtil.showInfoAlert(json.getString("message"),"文件生成成失败",window);
        }
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        ConfigEntity config = configService.findConfigById(1);
        sysConfigEntity = config;
        // 解析上一步所选txt文件
        GoodsList goodsList = goodsService.parseGoodsByFile(config.getSelectPath());
        if (goodsList == null) {
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/view/main.fxml"));
            Stage stage = VindamanagerApplication.showViewReturnStage(fxmlLoader);
            AlertUtil.showErrAlert("",stage,"文件格式有误");
            return;
        }
        // 计算订单各项金额
        goodsList = goodsService.calculateGoodsList(goodsList);
        // 合并同类商品
        goodsList = goodsService.mergeGoods(goodsList);
        // 将商品分类为正数，负数，超市奖励，金额调整
        goodsList = goodsService.changeFourList(goodsList);
        // 折扣金额
        goodsList.setZk(new BigDecimal(config.getDiscount())
                .add(new BigDecimal(goodsList.getZk())).doubleValue());
        goodsList.setSkr(config.getPayee());
        goodsList.setChecker(config.getChecker());
        // 根据是否勾选超市奖励和金额调整进行分类
        goodsList = goodsService.mainChange(config.getRate(),config.getIsSup(),config.getIsMon(),goodsList);
        // 初始化负数窗体
        fsTotalAmount.setText(String.valueOf(goodsList.getFsTotal()));
        showFsTableView(goodsList.getListFS());
        // 调整正数窗体数据
        goodsList = goodsService.adjustZsGoodsList(goodsList);
        // 初始化正数窗体
        showZsTableView(goodsList.getResultZS());
        // oracle金额
        oracleAmount.setText(String.valueOf(goodsList.getOracleTotalMon()));
        // 折扣金额
        discountAmount.setText(goodsList.getDistotalStr().replace("-",""));
        // 调整金额
        ceAmount.setText(String.valueOf(goodsList.getFsTotal()));
        // 金额合计
        String amount = goodsService.countTotalAmount(goodsList.getResultZS());
        totalAmount.setText(amount);
        // 不含税oracle
        String noRateOracle = new BigDecimal(goodsList.getOracleTotalMon())
                .divide(new BigDecimal(1).add(new BigDecimal(config.getRate())),2,BigDecimal.ROUND_HALF_UP)
                .toString();
        noRateOracleAmount.setText(noRateOracle);
        // 不含税折扣金额
        String noRateDis = new BigDecimal(goodsList.getDisTotal())
                .divide(new BigDecimal(1).add(new BigDecimal(config.getRate())),2,BigDecimal.ROUND_HALF_UP)
                .abs().toString();
        noRateDiscount.setText(noRateDis);
        // 当前折扣率
        disRate.setText(MathUtil.getFourPoint(goodsList.getDiscount() * 100) + "%  ");
        sysGoodList = goodsList;
    }



    //--------------------------------------界面其他初始化操作-----------------------------------------------

    private void showFsTableView(List<GoodsDetail> listFS) {
        fsIdCol.setCellValueFactory(new PropertyValueFactory<>("id"));
        fsNameCol.setCellValueFactory(new PropertyValueFactory<>("name"));
        fsNumCol.setCellValueFactory(new PropertyValueFactory<>("num"));
        fsAmountCol.setCellValueFactory(new PropertyValueFactory<>("mon"));
        fsSpecCol.setCellValueFactory(new PropertyValueFactory<>("type"));
        fsUnitCol.setCellValueFactory(new PropertyValueFactory<>("dw"));
        ObservableList<GoodsDetail> list = FXCollections.observableArrayList();
        for (int i = 0; i < listFS.size(); i++) {
            GoodsDetail goodsDetail = listFS.get(i);
            goodsDetail.setId(i+1);
            list.add(goodsDetail);
        }
        fsTableView.setItems(list);
    }

    private void showZsTableView(List<GoodsDetail> listZS) {
        zsIdCol.setCellValueFactory(new PropertyValueFactory<>("id"));
        zsNameCol.setCellValueFactory(new PropertyValueFactory<>("name"));
        zsNumCol.setCellValueFactory(new PropertyValueFactory<>("num"));
        zsAmountCol.setCellValueFactory(new PropertyValueFactory<>("mon"));
        zsSpecCol.setCellValueFactory(new PropertyValueFactory<>("type"));
        zsUnitCol.setCellValueFactory(new PropertyValueFactory<>("dw"));
        zsPriceCol.setCellValueFactory(new PropertyValueFactory<>("price"));
        zsDisCountCol.setCellValueFactory(new PropertyValueFactory<>("disMon"));
        adjustAmountCol.setCellValueFactory(new PropertyValueFactory<>("adjustMon"));
        // 设置金额调整列
        adjustAmountCol.setCellFactory(TextFieldTableCell.forTableColumn());
        adjustAmountCol.setOnEditCommit((TableColumn.CellEditEvent<GoodsDetail,String> t) ->{
            String temp = t.getNewValue();
            Window window = ((TableColumn) t.getSource()).getTableView().getScene().getWindow();
            if ("".equals(temp) || temp == null){
                temp = "0";
            }
            if (!StringUtils.isNumeric(temp)) {
                AlertUtil.showErrAlert("请填写正确的数字",window,"填写数字有误");
                return;
            }
            if (Double.valueOf(temp) < 0) {
                AlertUtil.showErrAlert("填写金额不能小于0",window,"填写数字有误");
                return;
            }
            GoodsDetail goodsDetail = t.getTableView().getItems().get(t.getTablePosition().getRow());
            // 求出上一次调整前原数量
            BigDecimal oldMon = new BigDecimal(goodsDetail.getMon()).add(new BigDecimal(goodsDetail.getAdjustMon() == null ? "0" : goodsDetail.getAdjustMon()));
            // 求出上一次调整前的调整金额
            BigDecimal oldCe = new BigDecimal(ceAmount.getText()).subtract(new BigDecimal(goodsDetail.getAdjustMon() == null ? "0" : goodsDetail.getAdjustMon()));
            // 求出上一次调整前金额合计
            BigDecimal oldTotal = new BigDecimal(totalAmount.getText()).add(new BigDecimal(goodsDetail.getAdjustMon() == null ? "0" : goodsDetail.getAdjustMon()));
            // 求出调整后金额
            BigDecimal  newValue = oldMon.subtract(new BigDecimal(temp).abs());
            // 求出调整后单价
            BigDecimal price = newValue.divide(new BigDecimal(goodsDetail.getNum()), 8, BigDecimal.ROUND_HALF_UP);
            goodsDetail.setMon(newValue.toString());
            goodsDetail.setPrice(price.doubleValue());
            goodsDetail.setAdjustMon(temp);
            zsTableView.refresh();
            ceAmount.setText(oldCe.add(new BigDecimal(temp)).toString());
            totalAmount.setText(oldTotal.subtract(new BigDecimal(temp)).toString());
        });
        adjustNumCol.setCellValueFactory(new PropertyValueFactory<>("adjustNum"));
        // 设置数量调整列
        adjustNumCol.setCellFactory(TextFieldTableCell.forTableColumn());
        adjustNumCol.setOnEditCommit((TableColumn.CellEditEvent<GoodsDetail,String> t) ->{
            String temp = t.getNewValue();
            Window window = ((TableColumn) t.getSource()).getTableView().getScene().getWindow();
            if ("".equals(temp) || temp == null){
                temp = "0";
            }
            if (!StringUtils.isNumeric(temp)) {
                AlertUtil.showErrAlert("请填写正确的数字",window,"填写数字有误");
                return;
            }
            GoodsDetail goodsDetail = t.getTableView().getItems().get(t.getTablePosition().getRow());
            // 求出上一次调整前原数量
            BigDecimal oldNum = new BigDecimal(goodsDetail.getNum()).add(new BigDecimal(goodsDetail.getAdjustNum() == null ? "0" : goodsDetail.getAdjustNum()));
            // 求出调整后数量
            BigDecimal  newValue = oldNum.subtract(new BigDecimal(temp).abs());
            // 求出调整后单价
            BigDecimal price = new BigDecimal(goodsDetail.getMon()).divide(newValue, 8, BigDecimal.ROUND_HALF_UP);
            goodsDetail.setNum(newValue.toString());
            goodsDetail.setPrice(price.doubleValue());
            goodsDetail.setAdjustNum(temp);
            zsTableView.refresh();
        });
        codeCol.setCellValueFactory(new PropertyValueFactory<>("ssflbm"));
        // 设置税收分类编码列可编辑
        codeCol.setCellFactory(TextFieldTableCell.forTableColumn());
        codeCol.setOnEditCommit((TableColumn.CellEditEvent<GoodsDetail,String> t) ->{
            String newValue = t.getNewValue();
            GoodsDetail goodsDetail = t.getTableView().getItems().get(t.getTablePosition().getRow());
            goodsDetail.setSsflbm(newValue);
        });

        ObservableList<GoodsDetail> list = FXCollections.observableArrayList();
        BigDecimal totalDis = new BigDecimal(0);
        for (int i = 0; i < listZS.size(); i++) {
            GoodsDetail goodsDetail = listZS.get(i);
            goodsDetail.setId(i+1);
            BigDecimal dis = new BigDecimal(goodsDetail.getDisMon()).setScale(2,BigDecimal.ROUND_HALF_UP);
            totalDis = totalDis.add(dis);
            goodsDetail.setDisMon(dis.toString());
            list.add(goodsDetail);
        }
        // 当前折扣金额
        disCount.setText(totalDis.toString());
        zsTableView.setItems(list);
    }

}
